//数组的使用

public class TestDemo {
    //1.保存数据
    public static void main1(String[] args) {
        int[] array = {1, 2, 3};
        for (int i = 0; i < array.length; ++i) {
            System.out.println(array[i] + " ");
        }
    }
    //2.作为函数的参数
    //2(1). 参数传基本数据类型
    public static void main2(String[] args) {
        int num = 0;
        func(num);
        System.out.println("num = " + num);
    }
    public static void func(int x) {
        x = 10;
        System.out.println("x = " + x);
    }
    //总结：发现在func方法中修改形参 x 的值, 不影响实参的 num 值.


    //2(2).参数传数组类型(引用数据类型)

    /**
     *  这种是改变了形参的指向（引用）
     *  在这种情况下，并不会影响到实参的指向
     */
    public static void func1(int[] array) {
        array = new int[10];//属于是对数组重新创建一个，这时候就会是改变了形参的指向
    }

    /**
     * 这时候是array得到了array2的地址，
     * 那么这个形参的array指向了栈上array2的对象，
     * 所以这个时候改变了形参array的数值，地址一样，那么也就是两者指向了一个对象
     * 所以对谁修改都会改变最后的对象的值
     * @param array
     */
    public static void func2(int[] array) {
        array[0] = 99;
    }
    //总结: 所谓的 "引用" 本质上只是存了一个地址. Java 将数组设定成引用类型, 这样的话后续进行数组参数传参, 其实
    //只是将数组的地址传入到函数形参中. 这样可以避免对整个数组的拷贝(数组可能比较长, 那么拷贝开销就会很大).
    public static void main3(String[] args) {
        int[] array1 = {1,2,3,4};
        func1(array1);
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + " ");
        }
        System.out.println();
        int[] array2 = {1,2,3,4};
        func2(array2);
        for (int i = 0; i < array2.length; i++) {
            System.out.print(array2[i] + " ");
        }
        System.out.println();
    }
    //func1在我原来的理解或许会打印为1，2，3，4，0，0···等
    //因为array1在main方法中，所以他会创建了array1，来保存它指向的地址，这个引用会指向array1的对象
    //但是当它进入到func1中，这时候也会在虚拟机的栈的func1方法上创建一个array（理解为载体）,在array中存进的array1（是地址）指向的对象也没有发生变化，
    //但是这个时候func1我们会创建一个新的变量array（这个array的地址存进了那个载体中去）,那么来储存array1（地址）的array（载体）的指向的对象就会发生变化，
    //那么它储存的地址也就会发生变化。所以最后的通过的func1的方法array1没有什么变化（其实变化也跟它没有相关的），
    //所以最后是1，2，3，4

    //总结： func1也就是改变了形参的指向（引用）
    //当然，你不要以为传了引用，就万事大吉了，你要想想你拿引用干些什么了

    //其实一句话：就是改变了形参的指向，要不变，就是原来的，要不是原来的，那就是改变了指向的对象
    //说了这么多：我的理解，类比C语言的指针，array[数字]，是对于同一块内存的中的内容发生改变，就是*p
    //array指向的改变，是地址的改变，即是从p = &a 改变到了 p = &b。
    //3.作为函数返回值

    /**
     * 在这个方法中首先创建了一个数组，在堆上就会显示它的对象的值，此时通过引用获得了地址，这个地址存在了虚拟机栈上
     * 再通过return，返回的array的地址
     * @return
     */
    public static int[] func3 (){
        int[] array = new int[]{1,2,3,4,5,6};
        return array;
    }
    public static void main(String[] args) {
        int[] ret = func3();
        //再通过ret接受func3所返回的array的地址,这时候通过地址指向了array的对象
        for (int i = 0; i < ret.length; i++) {
            System.out.print(ret[i] + " ");
        }
        //对象一定是在堆上，但是引用变量不一定是在栈上（后期会讲）
    }
}
